import uni_request from '../uni_request.js'
import {BASE_URL, ST_TOKEN,BASE_URL_SECURITY,REFRESH_TOKEN} from "@/constants/index.js"

const request = uni_request({ // 有效配置项只有三个
  baseURL: BASE_URL, //baseURL
  // timeout: 60*1000, // 超时时间，单位毫秒。默认 60 秒
  header: { 'Content-Type': 'application/x-www-form-urlencoded' }, // 设置请求头，建议放在请求拦截器中
  statusCode: [200, 401] // 服务器相应状态码为 200/401 时，网络请求不会 reject。也就是不会被 catch 到。如响应 401 时可以在响应拦截后 await 刷新 token + await 重新请求 + return response。即可实现无痛刷新。
});

//重新获取 access_token
const refreshToken = (refreshToken) => {
    return new Promise((resolve, reject) => {
		const params = {
			"grant_type": "refresh_token",
			"client_id": "web",
			"client_secret": "secret",
			"refresh_token": refreshToken
		} 
		request.post(BASE_URL_SECURITY+"/oauth/token",params).then(res => {
			uni.setStorageSync(ST_TOKEN,"bearer "+res.data.access_token)
			resolve(res.data.access_token);
		});
    }).catch(error => {
        reject(error)
    });
}

let refreshing = false; // 是否刷新token 默认是打开
let waitQueue = [];   // 请求队列

// 请求拦截器
request.interceptors.request.use(async (config, ...args) => {
	if (!BASE_URL) return;
  // await new Promise(resolve => setTimeout(() => resolve(), 3000))
  // console.log('请求拦截器, 网络请求会等 3 秒后上面的异步任务结束后执行') 
  // args[0] method args[1] url args[3] data
  //在当前页面显示导航条加载动画
  //uni.showNavigationBarLoading();
 if(typeof(args[2]) =="undefined" || typeof(args[2].isLoading) =="undefined" || args[2].isLoading == null){
	 uni.showNavigationBarLoading();
 }
 
  if (args[1] .indexOf("auth/oauth/token") ==-1) {
    config.header[ST_TOKEN] = uni.getStorageSync(ST_TOKEN); // 修改请求头
  }else{
	  config.header[ST_TOKEN] ='';
  }
  // config.body.test = 'test' // 修改请求体
  // config.cancel = true // 取消请求
  return config
})
// 响应拦截器
request.interceptors.response.use((response, ...args) => { // 响应拦截器（可以设置多个, 同时可以也可以使用异步方法）
  const { data: res } = response; // args[0] method args[1] url args[3] data
  // await new Promise(resolve => setTimeout(() => resolve(), 3000));
  //在当前页面显示导航条加载动画
  //uni.hideNavigationBarLoading();
  uni.hideNavigationBarLoading();
  if (res.code === 302 || res.code === 305) {
    // uni.clearStorageSync();
    uni.removeStorageSync(ST_TOKEN);
    uni.reLaunch({url: '/pages/login/index'})
  } 
  if(res.code === 301){
	// access_token过期 使用refresh_token刷新换取access_token
	const config = response.config;
	if (refreshing == false) {
	    refreshing = true;
	    const refresh_token = uni.getStorageSync(REFRESH_TOKEN);
	    return refreshToken(refresh_token).then((token) => {
	            //config.header[ST_TOKEN] = uni.getStorageSync(ST_TOKEN)
	            //config.baseURL = '' // 请求重试时，url已包含baseURL
	            waitQueue.forEach(callback => callback(token)) // 已刷新token，所有队列中的请求重试
	            waitQueue = [];
				refreshing = false;
	            return config;
	        }).catch((error) => { // refresh_token也过期，直接跳转登录页面重新登录
	            uni.reLaunch({url: '/pages/login/index'});
				uni.removeStorageSync(ST_TOKEN);
				uni.removeStorageSync(REFRESH_TOKEN);
	            refreshing = false;
	        })
	}else{
	    // 正在刷新token，返回未执行resolve的Promise,刷新token执行回调
	    return new Promise((resolve => {
	        waitQueue.push((token) => {
	            config.header[ST_TOKEN] = uni.getStorageSync(ST_TOKEN)
	            config.baseURL = '' // 请求重试时，url已包含baseURL
	            resolve(config)
	        })
	    }))
	}
  }
  return response
});

export default request;